package org.x.user.service.impl;


import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.x.common.config.BusinessException;
import org.x.user.dto.AclAssignDTO;
import org.x.user.dto.CreateRoleDTO;
import org.x.user.dto.RoleQueryDTO;
import org.x.user.dto.UpdateRoleDTO;
import org.x.user.entity.*;
import org.x.user.mapper.*;
import org.x.user.service.ISysRoleService;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.x.user.vo.RoleDetailVO;
import org.x.user.vo.RoleInfoVO;
import org.x.user.vo.RoleVO;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 角色表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRoleEntity> implements ISysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysRoleAclMapper sysRoleAclMapper;
    @Autowired
    private SysRoleUserMapper sysRoleUserMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysAclMapper sysAclMapper;

    /**
     * 查询角色列表
     * @return Page<RoleInfoVO>
     */
    @Transactional
    @Override
    public Page<RoleInfoVO> QueryRoleList(RoleQueryDTO roleQueryDTO) {

        QueryWrapper queryWrapper = new QueryWrapper();

        if(roleQueryDTO.getName() != null && !roleQueryDTO.getName().trim().isEmpty()){
            queryWrapper.like(SysRoleEntity::getName, roleQueryDTO.getName().trim());
        }
        if(roleQueryDTO.getCode() != null && !roleQueryDTO.getCode().trim().isEmpty()){
            queryWrapper.eq(SysRoleEntity::getCode, roleQueryDTO.getCode().trim());
        }

        // 确保分页参数有效
        int page = roleQueryDTO.getPage() > 0 ? roleQueryDTO.getPage() : 1;
        int size = roleQueryDTO.getSize() > 0 ? roleQueryDTO.getSize() : 10;


        Page<SysRoleEntity> paginate = sysRoleMapper.paginate(page, size, queryWrapper);

        List<SysRoleEntity> records = paginate.getRecords();

        //将paginate转为Page<RoleInfoVO>
        List<RoleInfoVO> list2 = new LinkedList<>();
        if (!records.isEmpty()) {
            records.forEach(role -> {
                RoleInfoVO roleInfoVO = new RoleInfoVO();
                roleInfoVO.setRoleId(role.getId());
                roleInfoVO.setName(role.getName());
                roleInfoVO.setCode(role.getCode());
                roleInfoVO.setDataScope(role.getDataScope());
                roleInfoVO.setCreateTime(role.getCreatedTime());

                // 查询权限数量
                QueryWrapper aclQuery = new QueryWrapper().eq(SysRoleAclEntity::getRoleId, role.getId());
                long aclCount = sysRoleAclMapper.selectCountByQuery(aclQuery);
                roleInfoVO.setAclCount(aclCount);

                list2.add(roleInfoVO);
            });
        }

        Page<RoleInfoVO> pageResult = new Page<>();
        pageResult.setRecords(list2);
        pageResult.setPageNumber(paginate.getPageNumber());
        pageResult.setPageSize(paginate.getPageSize());
        pageResult.setTotalRow(paginate.getTotalRow());
        pageResult.setTotalPage(paginate.getTotalPage());

        return pageResult;
    }

    /**
     * 创建角色
     *
     * @param createRoleDTO
     * @return
     */
    @Transactional
    @Override
    public RoleVO createRole(CreateRoleDTO createRoleDTO) {
        //校验角色名称是否已存在
        SysRoleEntity sysRoleEntity1 = sysRoleMapper.selectOneByQuery(new QueryWrapper().eq(SysRoleEntity::getName, createRoleDTO.getName()));
        if (sysRoleEntity1 != null) {
            throw new BusinessException("角色名称已存在");
        }
        //校验角色编码是否已存在
        SysRoleEntity sysRoleEntity2 = sysRoleMapper.selectOneByQuery(new QueryWrapper().eq(SysRoleEntity::getCode, createRoleDTO.getCode()));
        if (sysRoleEntity2 != null) {
            throw new BusinessException("角色编码已存在");
        }
        //创建角色
        SysRoleEntity sysRoleEntity = new SysRoleEntity();
        sysRoleEntity.setName(createRoleDTO.getName());
        sysRoleEntity.setCode(createRoleDTO.getCode());
        sysRoleEntity.setDataScope(createRoleDTO.getDataScope());
        sysRoleEntity.setCreatedBy(StpUtil.getLoginIdAsString());
        sysRoleEntity.setCreatedTime(new Date());
        sysRoleMapper.insert(sysRoleEntity);
        //分配权限点sys_role_acl
        SysRoleAclEntity sysRoleAclEntity = new SysRoleAclEntity();
        Set<Long> aclIds = new TreeSet<>(Arrays.asList(createRoleDTO.getAclIds()));
        sysRoleAclEntity.setRoleId(sysRoleEntity.getId());
        for(Long aclId : aclIds){
            sysRoleAclEntity.setAclId(aclId);
            sysRoleAclEntity.setCreatedTime(new Date());
            sysRoleAclMapper.insert(sysRoleAclEntity);
        }
        //返回角色ID
        RoleVO roleVO = new RoleVO();
        roleVO.setRoleId(sysRoleEntity.getId());
        return roleVO;
    }
    /**
     * 更新角色
     * @param updateRoleDTO
     * @return
     */
    @Transactional
    @Override
    public RoleVO updateRole(UpdateRoleDTO updateRoleDTO) {
        //校验角色存在性
        SysRoleEntity sysRoleEntity = sysRoleMapper.selectOneById(updateRoleDTO.getRoleId());
        if(sysRoleEntity == null){
            throw new BusinessException("角色不存在");
        }
        //更新角色
        sysRoleEntity.setName(updateRoleDTO.getName());
        sysRoleEntity.setCode(updateRoleDTO.getCode());
        sysRoleEntity.setDataScope(updateRoleDTO.getDataScope());
        sysRoleEntity.setUpdatedBy(StpUtil.getLoginIdAsString());
        sysRoleEntity.setUpdatedTime(new Date());
        sysRoleMapper.update(sysRoleEntity);

        RoleVO roleVO = new RoleVO();
        roleVO.setRoleId(sysRoleEntity.getId());
        return roleVO;
    }
    /**
     * 删除角色
     * @param roleId
     * @return 角色ID
     */
    @Transactional
    @Override
    public RoleVO deleteRole(Long roleId) {
        //校验角色存在性
        SysRoleEntity sysRoleEntity = sysRoleMapper.selectOneById(roleId);
        if(sysRoleEntity == null){
            throw new BusinessException("角色不存在");
        }
        //校验角色未分配给用户
        List<SysRoleUserEntity> sysRoleUserEntityList = sysRoleUserMapper.selectListByQuery(new QueryWrapper().eq(SysRoleUserEntity::getRoleId, roleId));
        if(!sysRoleUserEntityList.isEmpty()){
            throw new BusinessException("角色已分配给用户");
        }
        //删除角色
        sysRoleMapper.deleteById(roleId);
        //删除角色权限关联
        sysRoleAclMapper.deleteByQuery(new QueryWrapper().eq(SysRoleAclEntity::getRoleId, roleId));

        RoleVO roleVO = new RoleVO();
        roleVO.setRoleId(roleId);
        return roleVO;
    }
    /**
     * 获取角色详情
     * @param roleId
     * @return
     */
    @Transactional
    @Override
    public RoleDetailVO getDetail(Long roleId) {
        //校验角色存在性
        SysRoleEntity sysRoleEntity1 = sysRoleMapper.selectOneById(roleId);
        if(sysRoleEntity1 == null){
            throw new BusinessException("角色不存在");
        }
        RoleDetailVO roleDetailVO = new RoleDetailVO();
        SysRoleEntity sysRoleEntity2 = sysRoleMapper.selectOneById(roleId);
        roleDetailVO.setRoleId(sysRoleEntity2.getId());
        roleDetailVO.setName(sysRoleEntity2.getName());
        roleDetailVO.setCode(sysRoleEntity2.getCode());
        roleDetailVO.setDataScope(sysRoleEntity2.getDataScope());
        roleDetailVO.setCreateTime(sysRoleEntity2.getCreatedTime());
        List<SysRoleAclEntity> sysRoleAclEntities = sysRoleAclMapper.selectListByQuery(new QueryWrapper().eq(SysRoleAclEntity::getRoleId, roleId));
        List<SysAclEntity> sysAclEntities = sysAclMapper.selectListByIds(sysRoleAclEntities.stream().map(SysRoleAclEntity::getAclId).collect(Collectors.toList()));
        List<RoleDetailVO.AclList> aclList = sysAclEntities.stream().map(sysAclEntity -> {
            RoleDetailVO.AclList aclList1 = new RoleDetailVO.AclList();
            aclList1.setAclId(sysAclEntity.getId());
            aclList1.setName(sysAclEntity.getName());
            aclList1.setCode(sysAclEntity.getCode());
            return aclList1;
        }).collect(Collectors.toList());
        roleDetailVO.setAclList(aclList);
        return roleDetailVO;
    }
    /**
     * 分配角色权限
     */
    @Transactional
    @Override
    public RoleVO assignAcl(AclAssignDTO aclAssignDTO) {
        //校验角色存在性
        SysRoleEntity sysRoleEntity = sysRoleMapper.selectOneById(aclAssignDTO.getRoleId());
        if(sysRoleEntity == null){
            throw new BusinessException("角色不存在");
        }
        //校验权限点有效性
        for(Long aclId : aclAssignDTO.getAclIds()){
            if(sysAclMapper.selectOneById(aclId) == null){
                throw new BusinessException("权限点不存在");
            }
        }
        //删除角色权限点关系
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq(SysRoleAclEntity::getRoleId, aclAssignDTO.getRoleId());
        sysRoleAclMapper.deleteByQuery(queryWrapper);
        SysRoleAclEntity sysRoleAclEntity = new SysRoleAclEntity();
        sysRoleAclEntity.setRoleId(aclAssignDTO.getRoleId());
        for(Long aclId : aclAssignDTO.getAclIds()){
            sysRoleAclEntity.setAclId(aclId);
            sysRoleAclMapper.insert(sysRoleAclEntity);
        }
        RoleVO roleVO = new RoleVO();
        roleVO.setRoleId(sysRoleEntity.getId());
        return roleVO;
    }
}